home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
pcmagazi
/
1992
/
16
/
winclip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-03
|
5KB
|
240 lines
/*
WINCLIP.C -- DOS access to Windows Clipboard (Enhanced mode)
Copyright (c) 1992 Ziff Davis Communications
PC Magazine * Andrew Schulman (June 1992)
*/
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include <dos.h>
#include "winclip.h"
static int winoldap = 0;
static int clip_open = 0;
static int clip_init(void);
/* higher-level functions */
int WindowsClipboard(void)
{
return (IdentifyWinOldApVersion() != 0);
}
/* NOTE: len should include NULL-termination byte,
which is required */
int PutClipStrLen(char *s, unsigned len)
{
if (! winoldap)
if (! clip_init())
return 0;
if (! OpenClipboard())
return 0;
if (! EmptyClipboard())
{
CloseClipboard();
return 0; /* couldn't empty */
}
if (CompactClipboard(len) < len)
{
CloseClipboard();
return 0; /* couldn't compact */
}
if (! SetClipboardData(CF_TEXT, s, len))
{
CloseClipboard();
return 0; /* couldn't set */
}
CloseClipboard();
Yield();
return 1;
}
int PutClipString(char *str)
{
return PutClipStrLen(str, strlen(str)+1);
}
char *GetClipString(void)
{
unsigned long len;
char *s;
if (! winoldap)
if (! clip_init())
return (char *) 0;
if (! OpenClipboard())
return (char *) 0;
/* MUST do OpenClipboard BEFORE GetClipboardDataSize */
if ((len = GetClipboardDataSize(CF_TEXT)) == 0)
{
CloseClipboard();
return (char *) 0; /* nothing there */
}
if (len > (0xFFFFU - 16))
{
CloseClipboard();
return (char *) 0; /* too big */
}
if ((s = (char *) calloc((unsigned) len+1, 1)) == NULL)
{
CloseClipboard();
return (char *) 0; /* insufficient memory */
}
if (! GetClipboardData(CF_TEXT, s))
{
CloseClipboard();
return (char *) 0; /* couldn't get it */
}
CloseClipboard();
Yield();
return s;
}
void FreeClipString(char *s)
{
free(s);
}
/*********************************************************/
/* lower-level functions */
void sigint_handler(int sig)
{
if (clip_open != 0)
CloseClipboard();
exit(1);
}
void exit_func(void)
{
if (clip_open != 0)
CloseClipboard();
}
static int clip_init(void)
{
if (winoldap)
return 1; /* already did init */
if (! (winoldap = IdentifyWinOldApVersion()))
return 0;
/* install handlers so that we never exit holding
the clipboard open */
atexit(exit_func); /* at-exit handler */
signal(SIGINT, sigint_handler); /* Ctrl-C handler */
return 1;
}
unsigned long CompactClipboard(unsigned long len)
{
_asm push si
_asm mov ax, 1709h
_asm mov si, word ptr len+2
_asm mov cx, word ptr len
_asm int 2fh
_asm pop si
/* return value in DX:AX (size) */
}
unsigned CloseClipboard(void)
{
unsigned retval;
_asm mov ax, 1708h
_asm int 2fh
_asm mov retval, ax
if (retval) clip_open--;
Yield(); /* seems like a good place to put it */
return retval;
}
unsigned EmptyClipboard(void)
{
_asm mov ax, 1702h
_asm int 2fh
/* return value in AX (0 if failure) */
}
unsigned char far *GetClipboardData(CF_FORMAT format,
unsigned char far *buf)
{
unsigned retval;
_asm mov ax, 1705h
_asm mov dx, format
_asm les bx, buf
_asm int 2fh
_asm mov retval, ax
return retval? buf : (unsigned char far *) 0;
}
unsigned long GetClipboardDataSize(CF_FORMAT format)
{
_asm mov ax, 1704h
_asm mov dx, format
_asm int 2fh
/* return value in DX:AX (size) */
}
unsigned GetDeviceCaps(unsigned index)
{
_asm mov ax, 170Ah
_asm mov dx, index
_asm int 2fh
/* return value in AX (device capability) */
}
unsigned IdentifyWinOldApVersion(void)
{
unsigned vers;
_asm mov ax, 1700h
_asm int 2fh
_asm mov vers, ax
/* if AX still 1700h, then WINOLDAP not present */
return (vers == 0x1700) ? 0 : vers;
}
unsigned OpenClipboard(void)
{
unsigned retval;
_asm mov ax, 1701h
_asm int 2fh
_asm mov retval, ax
if (retval) clip_open++;
return retval;
}
unsigned SetClipboardData(CF_FORMAT format,
unsigned char far *buf, unsigned long len)
{
_asm push si /* save SI; compiler may use it */
_asm mov ax, 1703h /* SetClipboardData */
_asm mov dx, format /* CF_ format */
_asm les bx, buf /* far pointer to buffer */
_asm mov si, word ptr len+2 /* HIWORD of length */
_asm mov cx, word ptr len /* LOWORD of length */
_asm int 2fh /* call WINOLDAP API */
_asm pop si /* restore saved SI */
/* return value in AX (0 if failure) */
}
/* Problem: as soon as DOS box makes even one Yield, it
barely runs in the background anymore (especially in 3.1) */
void Yield(void)
{
#if 1
_asm int 28h
_asm int 28h
_asm int 28h
#else
_asm mov ax, 1680h
_asm int 2fh
#endif
}